Keep on coding

JavaScript - 函数 - 原型链


上一小节讲到了基本包装类型,本小节继续补充面向对象的内容.有点多,有点杂.好像我每次都在强调耐心这个词,确实,没有耐心是学不好技术的,如果讲的不够详细,大家又是似懂非懂的状态,这样与你与我都不好 !
所以我会很耐心的去分享,希望读者也有耐心去学习!

原型链 — 绘图展示

  • 示例代码 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
function Animal(){
}
function Dog(){
}
//设置原型链(原型)继承
var a1 = new Animal();
Dog.prototype = a1;
var dog1 = new Dog();
console.log(Object.prototype.constructor);
var o = {};
console.log(o.constructor == Object.prototype.constructor);
console.log(Object.prototype.__proto__ == Object.prototype);
</script>
  • 图解 – 更形象的展示原型链

 **原型链 **

Object对象的补充点

  • 创建基本包装类型的对象
  • js中所有的对象都基于object,都继承自object
  • 示例代码 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
var str1 = new String("demo01");
var str2 = new String("demo01");
var str3 = str1;
var str4 = "demo01";
//判断是否相等
console.log(str1 == str2); //false(!!!!)
console.log(str1 == str4); //true(内部会隐式转换)
console.log(str1 === str2); //false
console.log(str1 === str3); //true
console.log(str1 === str4); //false
var num1 = new Number(10);
var num2 = 10;
var num3 = new Number(10);
console.log(num1 == num2); //true
console.log(num1 == num3); //false
</script>

Object.prototype详解

  • constructor:指向该对象的构造函数
  • hasOwnProperty:检测对象中是否存在某个实例属性
  • isPrototypeOf:判断某个对象是否是指定对象的原型对象(会判断整条原型链)
  • propertyIsEnumerable:判断该属性是否是可枚举
    如果是可以枚举的,那么在使用for..in循环的时候可以打印出来
  • toString 返回一个对当前对象的字符串描述信息,并非一定是该对象的字符串形式

    1.object类型的对象 返回的什么 [obejct Object]
    2.其他对象类型如函数 | 数组 ,返回对应的字符串形式
    3.Number类型 可以传递参数(进制) 不传递参数:默认是十进制

  • toLocaleString 大部分情况下的等价于toString方法,特殊情况下会做本地化处理
  • valueOf 返回对应的值

    1.基本包装类型(String Number Boolean),返回对应的基本类型的值
    2.object类型的,返回this(该对象本身)
    3.date(日期类),返回时间戳

  • 示例代码1 :
1
2
3
4
5
6
7
8
9
10
11
12
<script>
function Person(){}
var obj = {name:"name"};
Person.prototype = obj; //替换原型对象
Person.constructor = Person;
var p1 = new Person();
console.log(obj.isPrototypeOf(p1)); //是原型对象
console.log(Object.prototype.isPrototypeOf(p1));
// true 整条原型链上面的原型对象都会进行判断
</script>
  • 示例代码2 :
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
var obj = {name:"张三",age:23};
//console.log(Object.getOwnPropertyDescriptor(obj, "name"));
//设置属性
Object.defineProperty(obj,"age",{
enumerable:false,
});
for(var k in obj)
{
console.log(k, obj[k]);
}
</script>
  • 示例代码3 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
var o = {name:"dingding"};
console.log(o.toString()); //[obejct Object]
var arr = ["demo01","demo02","demo03"];
console.log(arr.toString()); //demo01,demo02,demo03
function demoTest(){};
// console.log(demoTest.toString()); //function demoTest(){}
var num = new Number(10);
console.log(num.toString()); //20
console.log(num.toString(2)); //二进制 -- 1010 --- > 1 * 2*2*2 + 0 *2*2 + 1*2 + 0*1 = 8 + 0 + 2 + 0 = 10
console.log(num.toString(3)); //三进制 -- 101 ---> 1*3*3 + 0 * 3 + 1 *1 = 9 + 0 + 1 = 10
console.log(num.toString(7)); //七进制 -- 13 ---> 1 * 7 + 3*1 = 10
var str = new String("tese");
console.log(str.valueOf()); //tese
var o = {name:"jiji"};
console.log(o.valueOf());
var date = new Date(); //当前的时间
console.log(date.valueOf()); //1488163624297 时间戳,是一个绝对的值
</script>

Object的静态成员和实例成员

实例成员

  • 成员 : 属性和方法
  • 说明 : 实力对象上面添加的属性和方法

静态成员

  • 构造函数 : 本身也是对象,所以构造函数自己也可以拥有属性和方法,这些属性和方法就是静态成员

  • Object.apply –> 借用其它对象的函数

  • Object.arguments –>函数内部的一个隐藏参数,主要用来接收实参。
  • Object.assign –> 拷贝对象的属性的
  • Object.bind –> 绑定处理(call和apply很像)
  • Object.call –> 借用其它对象的函数
  • Object.caller
    某个函数的调用函数,返回的是一个函数
    如果是在全局作用域中调用该方法,那么打印出来的是:null而不是window
  • Object.constructor –> 构造器属性,指向该对象的构造函数
  • Object.create –> 创建对象,并且设置原型对象
  • Object.getPrototypeOf –> 获得某个对象的原型对象
  • Object.getOwnPropertyDescriptor
    获得对象中某个实例属性的描述信息(是否可以配置,枚举,值,是否可以重写)

    具体的描述信息如下:

    1.configurable:true 是否是可以配置的(能不能删除属性或者是修改这个配置本身)
    2.enumerable:true 是否是可以枚举的(在for..in循环中是否能够遍历出来|keys())
    3.value:”zhangsan” 属性对应的值
    4.writable:true 是否是可重写的

  • Object.defineProperty 用来设置属性的描述信息(修改已有的属性|新增属性)
    1.修改已有的属性,默认情况下这三个值是true
    2.新增加属性 默认情况下,这三个属性的值都是false
    • 示例代码 :
1
2
3
4
5
6
7
8
<script>
var obj = {};
//Object.defineProperty来新增属性并且设置属性的描述对象
Object.defineProperty(obj,"age",{
value:"100"
});
console.log(Object.getOwnPropertyDescriptor(obj, "age"));
</script>
  • Object.getOwnPropertyNames
    1.不包含原型属性
    2.获得所有的实例属性(名称),返回值是一个数组
  • 示例代码 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
var obj = {name:"zhangsan",age:78};
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getPrototypeOf(obj) == Object.prototype);
</script>
``
- **Object.keys --> 获得对象的key 不包含原型属性**
- **示例代码 :**
```javascript
<script>
function Person(){
this.name = "momo"
};
Person.prototype.say = "say";
var p1 = new Person();
console.log(Object.keys(p1));
console.log(Object.getOwnPropertyNames(p1));
</script>
  • Object.preventExtensions || Object.isExtensible –> 禁止对象扩展,默认情况下对象可以动态的增加属性,如果设置了禁止扩展,那么将无法增加属性
  • 示例代码 :
1
2
3
4
5
6
7
8
<script>
var o = {};
o.name = "names";
console.log(o);
Object.preventExtensions(o);
o.age = 30;
console.log(o);
</script>
  • Object.seal 密封对象 –> 禁止删除对象的属性,禁止修改对象的配置信息configurable,禁止扩展
  • Object.freeze 冻结对象 –> 不能删除属性,不能增加属性,也不能修改属性
  • 示例代码 :
1
2
3
4
5
6
7
8
9
10
11
<script>
var obj = {des:"des"};
Object.freeze(obj);
obj.name = "momo";
obj.age = 20;
console.log(obj);
delete obj.des;
console.log(obj);
obj.des = "能不能修改";
console.log(obj);
</script>
  • 或者你也可以打开控制台查看,都有! 想知道每个的功能可以一一去实验
  • 图解

**Object的静态成员**

Function的构造函数的使用

创建函数的几种方法

  • 函数声明
  • 函数表达式
  • 示例代码 :
1
2
3
4
5
6
7
8
9
10
11
<script>
function func01(){
//函数体
}
var func02 = function name(){}; //命名函数表达式
var func03 = function (){}; //匿名函数表达式
var func04 = new Function("console.log(\"1\");");
func04();
</script>
  • new Function
    1.一个参数都没有,那么创建的是一个空函数
    2.有一个参数,这个参数作为新创建出来的函数的函数体
    3.有多个参数,最后一个参数是新创建的函数的函数体,其它的参数是形参列表
  • 示例代码 :
1
2
3
4
5
6
7
<script>
// 操作符 + 拼接字符串的方式
var func = new Function("console.log(\"让我掉下眼泪的,不是昨夜的酒\");" +
" console.log(\"让我依依不舍的,不止你的温柔\");" +
"console.log(\"余路还要走多久,我牵着你的手\");");
func();
</script>
  • 示例代码 : —> 改进
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/template" id="demo">
// 使用js模板来存放数据
console.log("让我掉下眼泪的,不是昨夜的酒");
console.log("让我依依不舍的,不止你的温柔");
console.log("余路还要走多久,我牵着你的手");
</script>
<script>
var func = new Function(`
// 反括号``
console.log(\"让我掉下眼泪的,不是昨夜的酒\");
console.log(\"让我依依不舍的,不止你的温柔\");
console.log(\"余路还要走多久,我牵着你的手\");`);
func();
</script>
<script>
var script = document.getElementById("demo");
var str = script.innerHTML;
var func = new Function(str);
func();
</script>